package com.jie.component.mongo.wrapper;

import com.jie.component.mongo.util.MongoUtil;
import com.jie.component.mongo.util.MongoUtil.SFunction;
import lombok.Getter;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Collection;

@Getter
public class LambdaMongoUpdateWrapper<T> extends LambdaMongoQueryWrapper<T> {

    private final Update update = new Update();

    // 更新操作
    public <R> LambdaMongoUpdateWrapper<T> set(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.set(fieldName, value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> inc(SFunction<T, R> func, Number value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.inc(fieldName, value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> unset(SFunction<T, R> func) {
        String fieldName = MongoUtil.getFieldName(func);
        update.unset(fieldName);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> push(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).value(value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pushAll(SFunction<T, R> func, Collection<?> values) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).each(values.toArray());
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pull(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.pull(fieldName, value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pullAll(SFunction<T, R> func, Collection<?> values) {
        String fieldName = MongoUtil.getFieldName(func);
        update.pullAll(fieldName, values.toArray());
        return this;
    }

    // 数组操作方法
    public <R> LambdaMongoUpdateWrapper<T> addToSet(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.addToSet(fieldName).value(value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> addToSetAll(SFunction<T, R> func, Collection<?> values) {
        String fieldName = MongoUtil.getFieldName(func);
        update.addToSet(fieldName).each(values.toArray());
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pushFirst(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).atPosition(0).value(value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pushLast(SFunction<T, R> func, Object value) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).atPosition(-1).value(value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pushWithSlice(SFunction<T, R> func, Object value, int slice) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).slice(slice).value(value);
        return this;
    }

    public <R> LambdaMongoUpdateWrapper<T> pushAllWithSlice(SFunction<T, R> func, Collection<?> values, int slice) {
        String fieldName = MongoUtil.getFieldName(func);
        update.push(fieldName).slice(slice).each(values.toArray());
        return this;
    }
}